#include <QCoreApplication>
#include "Transaction.h"
#include "SwitchRecordStore.h"
#include "TimeUtil.h"
#include "SeqStamp.h"
#include "Table.h"
#include "RedoDataUtil.h"
#include "BitMap.h"
using namespace std;


QMutex IOUtil::recordFileMutex;
int64_t IOUtil::recordFileMaxLen;
int IOUtil::nameMaxLen;
string IOUtil::totalPath;
string IOUtil::recordFileName;
int Basic::dataMaxLen;
int ResourceManage::lockWaitTime;
int32_t SkipListIndex::compactThreshold;
uint64_t BitMap::byteCount;
TableInfoManager* TableInfoManager::manager;
ResourcePool* ResourcePool::blockPool;
ResourcePool* ResourcePool::blockDelPool;
ResourcePool* ResourcePool::indexPool;
ResourcePool* ResourcePool::bitMapPool;
TransactionPool* TransactionPool::transactionPool;
AsyncIncreWriteThread* AsyncIncreWriteThread::asyncIncreWriteThread;
QThreadPool* ThreadPools::commonAsyncClearThreadPool;
QThreadPool* ThreadPools::resourceAsyncClearThreadPool;



void printTable(const map<string, vector<Basic*>>& subTable){
    const int& rowCount = subTable.begin()->second.size();
    vector<string> colNameVec;
    for(auto it = subTable.begin(); it != subTable.end(); it++){
        cout << it->first + ' ';
        colNameVec.push_back(it->first);
    }
    cout << endl;
    for(int i = 0; i < rowCount; i++){
        for(const string& colName : colNameVec){
            cout << BasicUtil::toStr(subTable.at(colName)[i]) + ' ';
        }
        cout << endl;
    }
    cout << endl;
}



//class ResourcePoolTest{
//private:

//    ResourcePool* resPool;

//    vector<ResourceInfo> resInfoVec;
//public:

//    ResourcePoolTest(ResourcePool* resPool, vector<ResourceInfo>& resInfoVec){
//        this->resPool = resPool;
//        this->resInfoVec = resInfoVec;
//    }

//    void operator ()() {
//        for(int i = 0; i < 100; i++){
//            int ind = rand()%resInfoVec.size();
//            Block* tmpBlock;
//            tmpBlock = (Block*)resPool->getRes(resInfoVec[ind]);
//        }
//    }
//};



//class TPSTest : public QRunnable{
//public:

//    static QSemaphore sem;

//    int i;

//    TPSTest(int i){this->i = i;}

//    virtual void run () {
//        Transaction* transaction1 = TransactionPool::poolGetTransaction();
//        map<string, vector<Basic*>> addDatas;
//        vector<Basic*> ageAddDatas, nameAddDatas;
//        int64_t randNum = rand() % 1000000;
//        for(int j = 0; j < 1000; j++){
//            ageAddDatas.push_back(new Int(randNum + j));
//            nameAddDatas.push_back(new Str(to_string(randNum + j)));
//        }
//        addDatas["name"] = nameAddDatas;
//        addDatas["age"] = ageAddDatas;
//        TableOperator::addRowsData("school", "students", addDatas, transaction1);
//        transaction1->comit();
//        TransactionPool::poolPutTransaction(transaction1);
//        cout<<i<<endl;
//        sem.release();
//    }
//};
//QSemaphore TPSTest::sem;



//class QPSTest : public QRunnable{
//public:

//    static QSemaphore querySem;

//    string baseName;

//    string tableName;

//    string colName;

//    int i;

//    QPSTest(const string& baseName, const string& tableName, const string& colName, int i){
//        this->baseName = baseName;
//        this->tableName = tableName;
//        this->colName = colName;
//        this->i = i;
//    }

//    virtual void run(){
//        for(int i = 0; i < 62500; i++){
//            vector<Basic*> targetVec = {new Int(rand() % 20000000)};
//            TableOperator::snapShotDataSearch(baseName, tableName, colName, targetVec);
//        }
//        cout<<i<<endl;
//        querySem.release();
//    }

//};
//QSemaphore QPSTest::querySem;


void init(){
    //最后这些都读配置文件
    //设置数据最大长度
    Basic::setBasicDataMaxLen(20);
    //设置锁最长等待时间
    ResourceManage::setLockWaitTime(100000);
    //设置日志文件名
    IOUtil::setRecordFileName("records");
    //设置库名 表名 列名最大长度
    IOUtil::setNameMaxLen(15);
    //设置数据文件存储位置
    IOUtil::setTotalPath("Z:\\ColBase_test");
    //设置日志文件最大长度（超过则重置）
    IOUtil::setRecordFileMaxLen(1 << 24);
    //设置索引文件最大有序日志个数 （超过则归并重写）
    SkipListIndex::setCompactThreshold(100);
    //设置单个BitMap字节长度
    BitMap::initByteCount(1 << 16);
    //设置表信息分区个数（并行度）
    TableInfoManager::initManager(20);
    //设置资源池 缓存淘汰算法、容量、分区个数（并行度）
    ResourcePool::initBlockPool(LRU, 100, 20);
    ResourcePool::initBlockDelPool(LRU, 100, 20);
    ResourcePool::initIndexPool(LRU, 100, 20);
    ResourcePool::initBitMapPool(LRU, 100, 20);
    //设置数据库最大并行数
    TransactionPool::initTransactionPool(8);
    //设置触发异步写磁盘的阈值
    AsyncIncreWriteThread::init(10000);
    //



    try{RedoDataUtil::redoData();}
    catch (string str) {
        cout<<str<<endl;
    }
}



int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    init();






    //表创建演示
    //创建姓名字段，类型为字符串，不建立索引，hash取值从0到UINT64_MAX，分十个区。
    ColInfo* colTest1 = TableOperator::defAndGetColInfo("name", STR, false, 0, UINT64_MAX,10);
    //创建年龄字段，类型为int32，建立索引，hash取值从0，10000000，分五十个区。
    ColInfo* colTest2 = TableOperator::defAndGetColInfo("age", INT, true, 0, 150000, 50);
    //依据两个字段在school库下建名为students的表。
    TableOperator::tableInfoDef("school", "students", 1000, {colTest1, colTest2});




//    //数据写入演示，向数据库写入15w条数据。为方便演示年龄字段和姓名字段值一致。
    int64_t startTime = TimeUtil::getCurrentTime();
    Transaction* transaction1 = TransactionPool::poolGetTransaction();
    int tmpNum = 0;
    for(int i = 0; i < 15; i++){
        map<string, vector<Basic*>> addDatas;
        vector<Basic*> ageAddDatas, nameAddDatas;
        for(int j = 0; j < 10000; j++){
            ageAddDatas.push_back(new Int(tmpNum));
            nameAddDatas.push_back(new Str(to_string(tmpNum)));
            tmpNum++;
        }
        addDatas["name"] = nameAddDatas;
        addDatas["age"] = ageAddDatas;
        startTime = TimeUtil::getCurrentTime();
        TableOperator::addRowsData("school", "students", addDatas, transaction1);
        transaction1->comit();
        cout<<"costTime:" + to_string(TimeUtil::getCurrentTime() - startTime)<<endl;
        cout<<i<<endl;
    }
    cout<<endl;



    //当前读 找年龄为989的数据位置 并读取数据
    startTime = TimeUtil::getCurrentTime();
    map<int16_t, set<int>> mergeSortLocInfo = TableOperator::currentDataSearch("school", "students", "age", {new Int(989)}, READ, transaction1);
    map<string, vector<Basic*>> res = TableOperator::currentReadRowsData("school", "students", {"name", "age"}, mergeSortLocInfo, READ, transaction1);
    cout << "costTime:" + to_string(TimeUtil::getCurrentTime() - startTime) << endl;
    printTable(res);
    


    //将刚刚那条数据的年龄改为123321 再重新读取数据
    map<string, vector<Basic*>> modDatas;
    modDatas["age"] = {new Int(123321)};
    startTime = TimeUtil::getCurrentTime();
    TableOperator::modRowsData("school", "students", mergeSortLocInfo, modDatas, transaction1);
    transaction1->comit();
    res = TableOperator::currentReadRowsData("school", "students", {"name", "age"}, mergeSortLocInfo, READ, transaction1);
    cout << "costTime:" + to_string(TimeUtil::getCurrentTime() - startTime) << endl;
    printTable(res);
    


    //快照读（读写可以并行） 读取年龄大于等于149990的数据
    startTime = TimeUtil::getCurrentTime();
    mergeSortLocInfo = TableOperator::snapShotCeilingRangeDataSearch("school", "students", "age", new Int(149990));
    res = TableOperator::snapShotReadRowsData("school", "students", {"name", "age"}, mergeSortLocInfo);
    cout<<"costTime:" + to_string(TimeUtil::getCurrentTime() - startTime)<<endl;
    printTable(res);


    //多线程tps测试
    //每事务操作200条数据tps：单线程238 四线程353 十六线程436
    //每事务操作20条数据tps：八线程934  单线程833
    //每事务操作2条数据tps：八线程1754  单线程1886
//    int64_t startTime = TimeUtil::getCurrentTime();
//    int threadCount = 10000;
//    for(int i = 0; i < threadCount; i++){
//        QThreadPool::globalInstance()->start(new TPSTest(i));
//    }
//    TPSTest::sem.acquire(threadCount);

//    cout<<endl;
//    cout<<TimeUtil::getCurrentTime() - startTime<<endl;




    //多线程qps测试
    //单线程 qps：114942
    //四线程 qps：256410
    //十六线程 qps：154320
//    int64_t startTime = TimeUtil::getCurrentTime();
//    int threadCount = 16;
//    for(int i = 0; i < threadCount; i++){
//        QThreadPool::globalInstance()->start(new QPSTest("school", "students", "age", i));
//    }
//    QPSTest::querySem.acquire(threadCount);

//    cout<<endl;
//    cout<<TimeUtil::getCurrentTime() - startTime<<endl;






    //Row.h Col.h测试
//    ResourceInfo nameBlockResInfo1("school", "students", "name", 0, STR);
//    ResourceInfo nameBlockResInfo2("school", "students", "name", 1, STR);
//    ResourceInfo ageBlockResInfo1("school", "students", "age", 0, INT);
//    ResourceInfo ageBlockResInfo2("school", "students", "age", 1, INT);
//    ResourceInfo stuBlockDelResInfo1("school", "students", 0);
//    ResourceInfo stuBlockDelResInfo2("school", "students", 1);
//    ResourceInfo ageBitMapResInfo("school", "students", "age", 6);
//    ResourceInfo ageIndexResInfo("school", "students", "age", INT, 6);

//    Transaction* transaction1 = new Transaction();
//    Transaction* transaction2 = new Transaction();
//    map<string, vector<Basic*>> colAddDatas1;
//    colAddDatas1["name"] = {new Str("zt"), new Str("vv"), new Str("5v")};
//    colAddDatas1["age"] = {new Int(22), new Int(21), new Int(20)};

//    map<string, vector<Basic*>> colAddDatas2;
//    colAddDatas2["name"] = {new Str("ltz"), new Str("zx"), new Str("gwz"), new Str("zxy")};
//    colAddDatas2["age"] = {new Int(40), new Int(30), new Int(17), new Int(14)};

//    map<int16_t, set<int>> delLocInfoStore;
//    delLocInfoStore[0] = {0};

//    RowOperator::addRowsData(tableTest1, colAddDatas1, transaction1);
//    RowOperator::addRowsData(tableTest1, colAddDatas2, transaction2);

//    RowOperator::delRowsData(tableTest1, delLocInfoStore, transaction1);


//    transaction1->comit();
//    transaction2->comit();



//    map<int16_t, set<int>> modIndSet;
//    modIndSet[0] = {0, 1};
//    map<string, vector<Basic*>> modDatas;
//    modDatas["name"] = {(Basic*)new Str("zztt"), (Basic*)new Str("vvvv")};
//    modDatas["age"] = {(Basic*)new Int(28), (Basic*)new Int(27)};


//    RowOperator::modRowsData(tableTest1, modIndSet, modDatas, transaction1);

//    transaction1->comit();

//    RedoDataUtil::redoData();

//    Block* nameBlock1 = (Block*)ResourcePool::getRes(nameBlockResInfo1);
//    Block* nameBlock2 = (Block*)ResourcePool::getRes(nameBlockResInfo2);

//    Block* ageBlock1 = (Block*)ResourcePool::getRes(ageBlockResInfo1);
//    Block* ageBlock2 = (Block*)ResourcePool::getRes(ageBlockResInfo2);

//    BlockDel* blockDel1 = (BlockDel*)ResourcePool::getRes(stuBlockDelResInfo1);
//    BlockDel* blockDel2 = (BlockDel*)ResourcePool::getRes(stuBlockDelResInfo2);

//    BitMap* ageBitMap = (BitMap*)ResourcePool::getRes(ageBitMapResInfo);
//    SkipListIndex* ageIndex = (SkipListIndex*)ResourcePool::getRes(ageIndexResInfo);

//    for(int i = 20; i < 41; i++){
//        cout << ageBitMap->contains(i) << endl;
//    }

//    map<int16_t, set<int>> mergeSortLocInfo = ColOperator::snapShotDataSearch(tableTest1, "age", {new Int(13), new Int(14), new Int(15), new Int(16), new Int(17), new Int(18), new Int(20), new Int(22), new Int(28)});
//    map<int16_t, set<int>> nameMergeSortLocInfo = ColOperator::currentDataSearch(tableTest1, "name", {new Str("zt"), new Str("vv"), new Str("gwz"), new Str("ltz")}, READ, transaction1);

//    int64_t startTime = TimeUtil::getCurrentTime();
//    map<string, vector<Basic*>> res;
//    for(int i = 0; i < 1; i++)
//        res = RowOperator::currentReadRowsData(tableTest1, {"name", "age"}, mergeSortLocInfo, READ, transaction1);
//    cout << TimeUtil::getCurrentTime() - startTime << endl;
//    map<int16_t, set<int>> unDelLocInfoVec;
//    for(int i = 0; i < 1; i++)
//        unDelLocInfoVec = RowOperator::snapShotGetUnDelLocInfo(tableTest1, mergeSortLocInfo);
//    cout << TimeUtil::getCurrentTime() - startTime << endl;

//    vector<bool> judgeRes = ColOperator::currentBitMapJudge(tableTest1, "name", {new Str("zztt"), new Str("zzzz"), new Str("zt"), new Str("vv"), new Str("5v")}, READ, nullptr);











    // // 测试分区对象
    //    vector<int64_t> testContainer;
    //    for(int64_t i = 0; i < 10; i+=2){
    //        testContainer.push_back(i);
    //    }
    //    RangeEle<int64_t>* partTest = new RangeEle<int64_t>(testContainer, testContainer) ;

    //    int64_t res = partTest->getProbEle(1844674407370955163);

    //    partTest->addEle(5, 5);







        //测试记录序列化反序列化
//    Record testRecord("TestBase", "TestTable", "TestCol", 1, ADD, 34, new Str("zt"), new Str("ww"));
//    char* byteData = testRecord.getByteData();
//    Record testRecord2(byteData, STR);








    //测试block功能。
//    ResourceInfo resInfo("TestBase", "TestTable", "TestCol", 1, STR);
//    Block* testBlock = new Block(resInfo);

//    vector<string> addVec = {"1","2","3","89"};
//    testBlock->addData(addVec);

//    vector<int> modIndVec = {0, 1, 2, 3};
//    vector<string> modVec = {"3","4","5","98"};
//    testBlock->modData(modIndVec, modVec);

//    modIndVec = {1, 2};
//    modVec = {"7", "9"};
//    testBlock->modData(modIndVec, modVec);

//    testBlock->getComitRecords();

//    Block::increWriteToDisk(resInfo, testBlock->records);

//    //testBlock->writeToDisk();


//    addVec = {"1","2","3","89"};
//    testBlock->addData(addVec);

//    modIndVec = {0, 1, 2, 3};
//    modVec = {"4","5","6","99"};
//    testBlock->modData(modIndVec, modVec);

//    modIndVec = {1, 2};
//    modVec = {"8", "10"};
//    testBlock->modData(modIndVec, modVec);

//    //testBlock->memRollBack();

//    //testBlock->clearData();

//    Block* testBlock2 = (Block*)ResourcePool::getBlockPool()->getRes(resInfo);




//    //测试索引
//    ResourceInfo resInfo("TestBase", "TestTable", "TestCol", INT, 0);
//    SkipListIndex* index = new SkipListIndex(resInfo, 2);

//    int64_t startTime = TimeUtil::getCurrentTime();

////    int testNum = 100000;

////    for(int i = 0; i < testNum; i++){
////        index->put(new Int(i), new LocInfo(i+1, i+2));
////    }

//    index->put(new Int(78), new LocInfo(78, 79));
//    index->put(new Int(78), new LocInfo(80, 81));
//    index->put(new Int(78), new LocInfo(81, 82));

//    vector<LocInfo*> res = index->get(new Int(78));
//    res = index->getFloor(new Int(78));
//    res = index->getCeiling(new Int(78));
//    res = index->getLower(new Int(78));
//    res = index->getHigher(new Int(78));

//    vector<IndexRecord*> recVec = index->getComitIndexRecords();
//    SkipListIndex::increWriteToDisk(resInfo, recVec);
//    cout << TimeUtil::getCurrentTime() - startTime << endl;


//    SkipListIndex* index2 = new SkipListIndex(resInfo, 3);
//    index2->readFromDisk();
//    index2->remove(new Int(78), new LocInfo(78, 79));
//    index2->put(new Int(99), new LocInfo(100, 101));
//    recVec = index2->getComitIndexRecords();
//    SkipListIndex::increWriteToDisk(resInfo, recVec);
//    cout << TimeUtil::getCurrentTime() - startTime << endl;


//    SkipListIndex* index3 = new SkipListIndex(resInfo, 3);
//    index3->readFromDisk();
//    index3->put(new Int(78), new LocInfo(78, 79));
//    index3->remove(new Int(0), new LocInfo(1, 2));
//    recVec = index3->getComitIndexRecords();
//    SkipListIndex::increWriteToDisk(resInfo, recVec);
//    cout << TimeUtil::getCurrentTime() - startTime << endl;


//    SkipListIndex* index4 = new SkipListIndex(resInfo, 3);
//    index4->readFromDisk();
//    cout << TimeUtil::getCurrentTime() - startTime << endl;




//    //blockDel测试
//    ResourceInfo resInfo("TestBase", "TestTable", 0);
//    BlockDel* delTest = new BlockDel(resInfo);
//    for(int i = 0; i < 100; i += 2){
//        delTest->delEle(i);
//    }

//    delTest->writeToDisk();

//    BlockDel* delTest2 = new BlockDel(resInfo);
//    delTest2->readFromDisk();

//    for(int i = 1; i < 100; i += 2){
//        delTest2->delEle(i);
//    }

//    BlockDel::increWriteToDisk(resInfo, delTest2->getComitRecords());

//    BlockDel* delTest3 = new BlockDel(resInfo);
//    delTest3->readFromDisk();








////  资源池压力测试（qps：500000）
//    vector<ResourceInfo> resInfoVec;
//    for(int i = 0; i < 100; i++){
//        resInfoVec.push_back(ResourceInfo("TestBase", "TestTable", "TestCol", i, INT));
//    }

//    for(ResourceInfo& resInfo : resInfoVec){
//        Block* tmpBlock = new Block(resInfo);
//        vector<int> addVec;
//        for(int i = resInfo.getBlockNo(); i < resInfo.getBlockNo() + 5; i++){
//            addVec.push_back(i);
//        }
//        tmpBlock->addData(addVec);
//        tmpBlock->writeToDisk();
//        delete tmpBlock;
//    }

//    int64_t startTime = TimeUtil::getCurrentTime();
//    vector<thread*> threads;
//    for(int i = 0; i < 50; i++){
//        threads.push_back(new thread(ResourcePoolTest(ResourcePool::getBlockPool(), resInfoVec)));
//    }
//    for(thread* t : threads){
//        t->join();
//    }
//    ResourcePool::getBlockPool()->addCache(10000);
//    for(int i = 0; i < 50; i++){
//        threads.push_back(new thread(ResourcePoolTest(ResourcePool::getBlockPool(), resInfoVec)));
//    }
//    cout << TimeUtil::getCurrentTime() - startTime;

//    ResourcePool* resPool = ResourcePool::getBlockPool();








//    //跳表测试
//    SkipList<int*, LocInfo*>* skipListTest = new SkipList<int*, LocInfo*>(2);
//    int testNum = 100000;

//    int64_t startTime = TimeUtil::getCurrentTime();

//    for(int i = 0; i < testNum; i++){
//        skipListTest->insert(new int(i), new LocInfo(i+1, i+2));
//    }

//    skipListTest->insert(new int(78), new LocInfo(1, 2));
//    skipListTest->insert(new int(78), new LocInfo(2, 3));

//    //skipListTest->clear();

//    Node<int*, LocInfo*>* node = skipListTest->getFirstCeilingNode(new int(78));
//    node = skipListTest->getLastFloorNode(new int(78));

//    for(int i = 0; i < testNum; i++){
//        skipListTest->erase(new int(i), new LocInfo(i+1, i+2));
//    }

//    cout << TimeUtil::getCurrentTime() - startTime;




    //SwitchRecordStore测试

//    SwitchRecordStore* testStore = new SwitchRecordStore();

//    ResourceInfo blockInfo("base1", "table1", "col1", 4, INT);
//    ResourceInfo blockInfo2("base2", "table2", "col2", 4, INT);
//    ResourceInfo blockDelInfo("base1", "table1", 4);
//    ResourceInfo blockDelInfo2("base2", "table2", 4);
//    ResourceInfo slIndexInfo("base1", "table1", "col1", INT, 4);
//    ResourceInfo slIndexInfo2("base2", "table2", "col2", INT, 4);

//    vector<Record*> recVec;
//    vector<Record*> recVec2;
//    vector<Record*> delRecVec;
//    vector<Record*> delRecVec2;
//    vector<IndexRecord*> indRecVec;
//    vector<IndexRecord*> indRecVec2;

//    recVec.push_back(new Record("base1", "table1", "col1", 4, ADD, 0, nullptr, new Int(3)));
//    recVec.push_back(new Record("base1", "table1", "col1", 4, ADD, 1, nullptr, new Int(33)));
//    recVec.push_back(new Record("base1", "table1", "col1", 4, MOD, 1, new Int(33), new Int(34)));
//    delRecVec.push_back(new Record("base1", "table1", "", 4, DEL, 1, nullptr, nullptr));
//    indRecVec.push_back(new IndexRecord(new Int(78), new LocInfo(2,4), INDADD));
//    indRecVec.push_back(new IndexRecord(new Int(8), new LocInfo(6,4), INDADD));


//    recVec2.push_back(new Record("base1", "table1", "col1", 4, ADD, 0, nullptr, new Int(3)));
//    recVec2.push_back(new Record("base1", "table1", "col1", 4, ADD, 1, nullptr, new Int(33)));
//    recVec2.push_back(new Record("base1", "table1", "col1", 4, MOD, 1, new Int(33), new Int(34)));
//    delRecVec2.push_back(new Record("base1", "table1", "", 4, DEL, 1, nullptr, nullptr));
//    indRecVec2.push_back(new IndexRecord(new Int(78), new LocInfo(2,4), INDADD));
//    indRecVec2.push_back(new IndexRecord(new Int(8), new LocInfo(6,4), INDADD));

//    testStore->addComitInfo({make_pair(blockInfo, recVec), make_pair(blockDelInfo, delRecVec),
//                             make_pair(blockInfo2, recVec2), make_pair(blockDelInfo2, delRecVec2)},
//                            {make_pair(slIndexInfo, indRecVec), make_pair(slIndexInfo2, indRecVec2)});
//    testStore->increWriteToDisk();

//    Block* blockTest = new Block(blockInfo);
//    blockTest->readFromDisk();
//    BlockDel* blockDelTest = new BlockDel(blockDelInfo);
//    blockDelTest->readFromDisk();
//    SkipListIndex<Int*>* indTest = new SkipListIndex<Int*>(slIndexInfo);
//    indTest->readFromDisk();

//    Block* blockTest2 = new Block(blockInfo2);
//    blockTest2->readFromDisk();
//    BlockDel* blockDelTest2 = new BlockDel(blockDelInfo2);
//    blockDelTest2->readFromDisk();
//    SkipListIndex<Int*>* indTest2 = new SkipListIndex<Int*>(slIndexInfo2);
//    indTest2->readFromDisk();





//    //事务提交后异步增量修改数据库测试
//    ResourceInfo resInfo("school", "students", "name", 1, STR);
//    ResourceInfo bitMapInfo("school", "students", "name", 0);
//    Block* testBlock = new Block(resInfo);
//    BitMap* testBm = new BitMap(bitMapInfo);
//    //testBlock->readFromDisk();
//    Transaction* tranTest = new Transaction();
//    int64_t startTime = TimeUtil::getCurrentTime();
////    for(int i = 0; i < 100; i++){
////        tranTest->tryGetResource(new Block(resInfo), READ);
////    }
//    tranTest->tryGetResource(testBlock, READ);
//    tranTest->tryGetResource(testBlock, WRITE);
//    tranTest->tryGetResource(testBm, WRITE);
//    cout << TimeUtil::getCurrentTime() - startTime;

//    vector<string> addVec = {"1","2","3","89"};
//    vector<int> modIndVec = {3};
//    vector<string> modVec = {"1"};
//    testBlock->addData(addVec);
//    testBlock->modData(modIndVec, modVec);
//    testBm->put(123);

//    tranTest->comit();

//    vector<Record*> redoRecVec = Record::readRedoDataRecords();

//    Block* testBlock2 = (Block*)ResourcePool::getRes(resInfo);
//    BitMap* testBm2 = (BitMap*)ResourcePool::getRes(bitMapInfo);
//    for(int i = 120; i < 125; i++){
//        cout << testBm2->contains(i) <<endl;
//    }




    //测试IndexRecord序列化反序列化
//    IndexRecord<Int*>* indRec = new IndexRecord<Int*>(new Int(56), new LocInfo(2,0), INDDEL);
//    char* byteDate = indRec->getByteData();
//    IndexRecord<Int*>* indRec2 = new IndexRecord<Int*>(byteDate, INT);




    //redoDataUtil测试
//    ResourceInfo resInfo("TestBase", "TestTable", "TestCol", 1, INT);
//    ResourceInfo delInfo("TestBase", "TestTable", 1);
//    ResourceInfo indexResInfo("TestBase", "TestTable", "TestCol", INT, 0);
//    ResourceInfo indexResInfo2("TestBase", "TestTable", "TestCol", INT, 65);
//    ResourceInfo bitMapResInfo("TestBase", "TestTable", "TestCol", 0);
//    ResourceInfo bitMapResInfo2("TestBase", "TestTable", "TestCol", 65);
//    ColInfo* colTest1 = new ColInfo("TestCol", INT, true, {0,65});

//    TableOperator::tableInfoDef("TestBase", "TestTable", 10, {colTest1});

//    TableInfo* tableTest1 = TableInfoManager::getTableInfo("TestBase", "TestTable");

//    Block* testBlock = new Block(resInfo);
//    BlockDel* testBlockDel = new BlockDel(delInfo);
//    Transaction* tranTest = new Transaction();
//    tranTest->getResLock(testBlock, WRITE);
//    tranTest->getResLock(testBlockDel, WRITE);
//    vector<Basic*> addVec = {new Int(1), new Int(2), new Int(3), new Int(89)};
//    vector<int> modIndVec = {3};
//    vector<Basic*> modVec = {new Int(1)};
//    testBlock->addData(addVec);
//    testBlock->modData(modIndVec, modVec);
//    testBlock->addData(addVec);
//    testBlockDel->delEle(5);

//    tranTest->comit();

    //vector<Record*> redoRecVec = Record::readRedoDataRecords();
//    RedoDataUtil::redoData();   //数据重做

//    Block* testBlock2 = new Block(resInfo);
//    BlockDel* testBlockDel2 = new BlockDel(delInfo);
//    SkipListIndex* slIndex = new SkipListIndex(indexResInfo);
//    SkipListIndex* slIndex2 = new SkipListIndex(indexResInfo2);
//    BitMap* bitMap = new BitMap(bitMapResInfo);
//    BitMap* bitMap2 = new BitMap(bitMapResInfo2);
//    testBlock2->readFromDisk();
//    testBlockDel2->readFromDisk();
//    slIndex->readFromDisk();
//    slIndex2->readFromDisk();
//    bitMap->readFromDisk();
//    bitMap2->readFromDisk();
//    for(int i = 0; i < 5; i++){
//        cout << bitMap->contains(i) << endl;
//    }
//    cout << endl;
//    for(int i = 65; i < 90; i++){
//        cout << bitMap2->contains(i) << endl;
//    }




    //BitMap测试
//    ResourceInfo resInfo("BaseName", "TabelName", "ColName", 0);
//    BitMap* bitMap = new BitMap(resInfo);
//    for(uint64_t i = 0; i < 100000; i += 2){
//        bitMap->put(i);
//    }

//    for(uint64_t i = 0; i < 10; i++){
//        cout << bitMap->contains(i) << endl;
//    }

//    bitMap->memRollBack();

//    for(uint64_t i = 0; i < 10; i++){
//        cout << bitMap->contains(i) << endl;
//    }

////    bitMap->writeToDisk();
////    BitMap* bitMap2 = new BitMap(resInfo);
////    bitMap2->readFromDisk();
////    for(int i = 0; i < 100000; i += 1){
////        cout << bitMap2->contains(i) << endl;
////    }

//    vector<uint64_t> records;
//    for(uint64_t i = 0; i < 100000; i += 2){
//        records.push_back(i);
//    }
//    BitMap::increWriteToDisk(resInfo, records);
//    BitMap* bitMap2 = new BitMap(resInfo);
//    bitMap2->readFromDisk();

//    for(uint64_t i = 0; i < 100000; i += 1){
//        cout << bitMap2->contains(i) << endl;
//    }








    return a.exec();
}
